package com.assertionerror.loccounter.ui;

import com.assertionerror.loccounter.FileTypes;
import com.assertionerror.loccounter.engine.FileReadEvent;
import com.assertionerror.loccounter.engine.FileReadListener;
import com.assertionerror.loccounter.engine.FileRecursor;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author <a href="mailto:petrus@codewave.co.za">Petrus Pelser</a>
 */
public class CounterForm {
    private JTextField basePath;
    private JCheckBox chkJava;
    private JCheckBox chkXML;
    private JCheckBox chkHTML;
    private JCheckBox chkCSS;
    private JButton btnCalc;
    private JLabel lblCount;
    private JProgressBar progressBar;
    private JLabel filenameLabel;
    private JCheckBox jspCheckBox;
    private JCheckBox jsCheckBox;
    private JLabel lblFileCount;
    private JPanel mainPanel;

    public CounterForm() {
        resetFields();

        btnCalc.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                enableFields(false);
                resetFields();

                ArrayList<FileTypes> types = getSelected();
                countFiles(types);
                countLines(types);
            }
        });
    }

    private void enableFields(boolean enabled) {
        btnCalc.setEnabled(enabled);
        basePath.setEnabled(enabled);

        Cursor cursor = new Cursor(enabled ? Cursor.DEFAULT_CURSOR : Cursor.WAIT_CURSOR);
        mainPanel.setCursor(cursor);
    }

    private void countLines(ArrayList<FileTypes> types) {
        final File file = new File(basePath.getText());
        final FileRecursor rec = new FileRecursor(file, types);

        rec.addFileReadListener(new FileReadListener() {
            public void onRead(FileReadEvent event) {
                // set the progress bar
                Integer newVal = progressBar.getValue() + 1;
                if (newVal > progressBar.getMaximum()) {
                    progressBar.setMaximum(newVal + 10);
                }
                progressBar.setValue(newVal);

                filenameLabel.setText(event.getFileName());
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                Integer count = 0;
                try {
                    count = rec.recurseDirectory();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                lblCount.setText(count.toString());
                filenameLabel.setText("");
                enableFields(true);
            }
        });
        t2.start();
    }

    private void countFiles(final ArrayList<FileTypes> types) {
        final File file = new File(basePath.getText());
        final FileRecursor rec = new FileRecursor(file, types);

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    Integer filecount = rec.getFileCount(file);
                    progressBar.setMaximum(filecount);
                    lblFileCount.setText(filecount.toString());
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });
        t1.start();
    }

    private ArrayList<FileTypes> getSelected() {
        ArrayList<FileTypes> types = new ArrayList<FileTypes>();

        if (chkJava.isSelected()) {
            types.add(FileTypes.JAVA);
        }
        if (jspCheckBox.isSelected()) {
            types.add(FileTypes.JSP);
        }
        if (jsCheckBox.isSelected()) {
            types.add(FileTypes.JS);
        }
        if (chkHTML.isSelected()) {
            types.add(FileTypes.HTML);
        }
        if (chkCSS.isSelected()) {
            types.add(FileTypes.CSS);
        }
        if (chkXML.isSelected()) {
            types.add(FileTypes.XML);
        }

        return types;
    }

    private void resetFields() {
        lblFileCount.setText("");
        lblCount.setText("");
        filenameLabel.setText("");

        progressBar.setValue(0);
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }
}
